/*
	This file is part of Erosion, a clone of Qix
	Copyright (c) 2009 Bill Whitacre

	Permission is hereby granted, free of charge, to any person obtaining a copy
	of this software and associated documentation files (the "Software"), to deal
	in the Software without restriction, including without limitation the rights
	to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
	copies of the Software, and to permit persons to whom the Software is
	furnished to do so, subject to the following conditions:

	The above copyright notice and this permission notice shall be included in
	all copies or substantial portions of the Software.

	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
	AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
	OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
	THE SOFTWARE.
*/

#ifndef KEYMAP_H
#define KEYMAP_H

#if defined(__linux__)
#	include <X11/X.h>
#	include <X11/keysym.h>
#elif defined(WIN32)||defined(_WIN32)||defined(__WIN32)||\
	defined(__WIN32__)||defined(Win32)
#	include <windows.h>
#endif

#include <stdlib.h>
#include <string.h>

typedef unsigned int RAT_KEY_CODE;

#define RAT_KEY_LBUTTON            0x01   // Left mouse button
#define RAT_KEY_RBUTTON            0x02   // Right mouse button
#define RAT_KEY_CANCEL             0x03   // Control-break processing
#define RAT_KEY_MBUTTON            0x04   // Middle mouse button (three-button mouse)
#define RAT_KEY_XBUTTON1           0x05   // Windows 2000/XP: X1 mouse button
#define RAT_KEY_XBUTTON2           0x06   // Windows 2000/XP: X2 mouse button
#define RAT_KEY_BACK               0x08   // BACKSPACE key
#define RAT_KEY_TAB                0x09   // TAB key
#define RAT_KEY_CLEAR              0x0C   // CLEAR key
#define RAT_KEY_RETURN             0x0D   // ENTER key
#define RAT_KEY_SHIFT              0x10   // SHIFT key
#define RAT_KEY_CONTROL            0x11   // CTRL key
#define RAT_KEY_MENU               0x12   // ALT key
#define RAT_KEY_PAUSE              0x13   // PAUSE key
#define RAT_KEY_CAPITAL            0x14   // CAPS LOCK key
#define RAT_KEY_KANA               0x15   // IME Kana mode
#define RAT_KEY_HANGUEL            0x15   // IME Hanguel mode (maintained for compatibility use RAT_KEY_HANGUL)
#define RAT_KEY_HANGUL             0x15   // IME Hangul mode
#define RAT_KEY_JUNJA              0x17   // IME Junja mode
#define RAT_KEY_FINAL              0x18   // IME final mode
#define RAT_KEY_HANJA              0x19   // IME Hanja mode
#define RAT_KEY_KANJI              0x19   // IME Kanji mode
#define RAT_KEY_ESCAPE             0x1B   // ESC key
#define RAT_KEY_CONVERT            0x1C   // IME convert
#define RAT_KEY_NONCONVERT         0x1D   // IME nonconvert
#define RAT_KEY_ACCEPT             0x1E   // IME accept
#define RAT_KEY_MODECHANGE         0x1F   // IME mode change request
#define RAT_KEY_SPACE              0x20   // SPACEBAR
#define RAT_KEY_PRIOR              0x21   // PAGE UP key
#define RAT_KEY_NEXT               0x22   // PAGE DOWN key
#define RAT_KEY_END                0x23   // END key
#define RAT_KEY_HOME               0x24   // HOME key
#define RAT_KEY_LEFT               0x25   // LEFT ARROW key
#define RAT_KEY_UP                 0x26   // UP ARROW key
#define RAT_KEY_RIGHT              0x27   // RIGHT ARROW key
#define RAT_KEY_DOWN               0x28   // DOWN ARROW key
#define RAT_KEY_SELECT             0x29   // SELECT key
#define RAT_KEY_PRINT              0x2A   // PRINT key
#define RAT_KEY_EXECUT             0x2B   // EXECUTE key
#define RAT_KEY_SNAPSHOT           0x2C   // PRINT SCREEN key
#define RAT_KEY_INSERT             0x2D   // INS key
#define RAT_KEY_DELETE             0x2E   // DEL key
#define RAT_KEY_HELP               0x2F   // HELP key
#define RAT_KEY_KEY_0           0x30   // 0 key
#define RAT_KEY_KEY_1           0x31   // 1 key
#define RAT_KEY_KEY_2           0x32   // 2 key
#define RAT_KEY_KEY_3           0x33   // 3 key
#define RAT_KEY_KEY_4           0x34   // 4 key
#define RAT_KEY_KEY_5           0x35   // 5 key
#define RAT_KEY_KEY_6           0x36   // 6 key
#define RAT_KEY_KEY_7           0x37   // 7 key
#define RAT_KEY_KEY_8           0x38   // 8 key
#define RAT_KEY_KEY_9           0x39   // 9 key
#define RAT_KEY_KEY_A           0x41   // A key
#define RAT_KEY_KEY_B           0x42   // B key
#define RAT_KEY_KEY_C           0x43   // C key
#define RAT_KEY_KEY_D           0x44   // D key
#define RAT_KEY_KEY_E           0x45   // E key
#define RAT_KEY_KEY_F           0x46   // F key
#define RAT_KEY_KEY_G           0x47   // G key
#define RAT_KEY_KEY_H           0x48   // H key
#define RAT_KEY_KEY_I           0x49   // I key
#define RAT_KEY_KEY_J           0x4A   // J key
#define RAT_KEY_KEY_K           0x4B   // K key
#define RAT_KEY_KEY_L           0x4C   // L key
#define RAT_KEY_KEY_M           0x4D   // M key
#define RAT_KEY_KEY_N           0x4E   // N key
#define RAT_KEY_KEY_O           0x4F   // O key
#define RAT_KEY_KEY_P           0x50   // P key
#define RAT_KEY_KEY_Q           0x51   // Q key
#define RAT_KEY_KEY_R           0x52   // R key
#define RAT_KEY_KEY_S           0x53   // S key
#define RAT_KEY_KEY_T           0x54   // T key
#define RAT_KEY_KEY_U           0x55   // U key
#define RAT_KEY_KEY_V           0x56   // V key
#define RAT_KEY_KEY_W           0x57   // W key
#define RAT_KEY_KEY_X           0x58   // X key
#define RAT_KEY_KEY_Y           0x59   // Y key
#define RAT_KEY_KEY_Z          	0x5A   // Z key
#define RAT_KEY_LSUPER             0x5B   // Left Super (sometimes windows) key (Natural keyboard)
#define RAT_KEY_RSUPER             0x5C   // Left Super (sometimes windows) key (Natural keyboard)
#define RAT_KEY_APPS               0x5D   // Applications key (Natural keyboard)
#define RAT_KEY_SLEEP              0x5F   // Computer Sleep key
#define RAT_KEY_NUMPAD0            0x60   // Numeric keypad 0 key
#define RAT_KEY_NUMPAD1            0x61   // Numeric keypad 1 key
#define RAT_KEY_NUMPAD2            0x62   // Numeric keypad 2 key
#define RAT_KEY_NUMPAD3            0x63   // Numeric keypad 3 key
#define RAT_KEY_NUMPAD4            0x64   // Numeric keypad 4 key
#define RAT_KEY_NUMPAD5            0x65   // Numeric keypad 5 key
#define RAT_KEY_NUMPAD6            0x66   // Numeric keypad 6 key
#define RAT_KEY_NUMPAD7            0x67   // Numeric keypad 7 key
#define RAT_KEY_NUMPAD8            0x68   // Numeric keypad 8 key
#define RAT_KEY_NUMPAD9            0x69   // Numeric keypad 9 key
#define RAT_KEY_MULTIPLY           0x6A   // Multiply key
#define RAT_KEY_ADD                0x6B   // Add key
#define RAT_KEY_SEPARATOR          0x6C   // Separator key
#define RAT_KEY_SUBTRACT           0x6D   // Subtract key
#define RAT_KEY_DECIMAL            0x6E   // Decimal key
#define RAT_KEY_DIVIDE             0x6F   // Divide key
#define RAT_KEY_F1                 0x70   // F1 key
#define RAT_KEY_F2                 0x71   // F2 key
#define RAT_KEY_F3                 0x72   // F3 key
#define RAT_KEY_F4                 0x73   // F4 key
#define RAT_KEY_F5                 0x74   // F5 key
#define RAT_KEY_F6                 0x75   // F6 key
#define RAT_KEY_F7                 0x76   // F7 key
#define RAT_KEY_F8                 0x77   // F8 key
#define RAT_KEY_F9                 0x78   // F9 key
#define RAT_KEY_F10                0x79   // F10 key
#define RAT_KEY_F11                0x7A   // F11 key
#define RAT_KEY_F12                0x7B   // F12 key
#define RAT_KEY_F13                0x7C   // F13 key
#define RAT_KEY_F14                0x7D   // F14 key
#define RAT_KEY_F15                0x7E   // F15 key
#define RAT_KEY_F16                0x7F   // F16 key
#define RAT_KEY_F17                0x80   // F17 key
#define RAT_KEY_F18                0x81   // F18 key
#define RAT_KEY_F19                0x82   // F19 key
#define RAT_KEY_F20                0x83   // F20 key
#define RAT_KEY_F21                0x84   // F21 key
#define RAT_KEY_F22                0x85   // F22 key
#define RAT_KEY_F23                0x86   // F23 key
#define RAT_KEY_F24                0x87   // F24 key
#define RAT_KEY_NUMLOCK            0x90   // NUM LOCK key
#define RAT_KEY_SCROLL             0x91   // SCROLL LOCK key
#define RAT_KEY_LSHIFT             0xA0   // Left SHIFT key
#define RAT_KEY_RSHIFT             0xA1   // Right SHIFT key
#define RAT_KEY_LCONTROL           0xA2   // Left CONTROL key
#define RAT_KEY_RCONTROL           0xA3   // Right CONTROL key
#define RAT_KEY_LMENU              0xA4   // Left MENU key
#define RAT_KEY_RMENU              0xA5   // Right MENU key
#define RAT_KEY_PLUS               0xBB   // Plus Key   (+)
#define RAT_KEY_COMMA              0xBC   // Comma Key  (,)
#define RAT_KEY_MINUS              0xBD   // Minus Key  (-)
#define RAT_KEY_PERIOD             0xBE   // Period Key (.)
#define RAT_KEY_ATTN               0xF6   // Attn key
#define RAT_KEY_CRSEL              0xF7   // CrSel key
#define RAT_KEY_EXSEL              0xF8   // ExSel key
#define RAT_KEY_EREOF              0xF9   // Erase EOF key
#define RAT_KEY_PLAY               0xFA   // Play key
#define RAT_KEY_ZOOM               0xFB   // Zoom key
#define RAT_KEY_PA1                0xFD   // PA1 key
#define RAT_KEY_OEM_CLEAR          0xFE   // Clear key
#define RAT_KEY_CODE_COUNT         0xFF   // number of keycodes (255. beautiful.)

#if defined(__linux__)
    typedef KeySym RAT_SYS_KEY;
#elif defined(WIN32)||defined(_WIN32)||defined(__WIN32)||\
	defined(__WIN32__)||defined(Win32)
    typedef long RAT_SYS_KEY;
#endif

typedef struct rat_key_pair
{
    RAT_KEY_CODE rekey;
    RAT_SYS_KEY syskey;
} rat_key_pair;

typedef struct rat_key_map
{
    int numpairs;
    rat_key_pair *keypairs;
} rat_key_map;

rat_key_pair rat_key_pair_create(RAT_SYS_KEY syskey,RAT_KEY_CODE rekey);

rat_key_map *rat_key_map_create();
void rat_key_map_destroy(rat_key_map *keymap);

void rat_key_map_add_pair(rat_key_map *keymap,rat_key_pair keypair);
RAT_KEY_CODE rat_key_map_get_code(rat_key_map *keymap,RAT_SYS_KEY syskey);

void rat_key_map_sort(rat_key_map *keymap);

#endif
